package com.definity.toolkit.ui.widget;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.BoxLayout;
import javax.swing.JPanel;

import com.definity.toolkit.ui.Body;
import com.definity.toolkit.ui.Position;
import com.definity.toolkit.ui.widget.paint.Paint;

public class GridPanel extends JPanel implements Widget<GridPanel>, WidgetPaint<GridPanel> {

	private static final long serialVersionUID = 2618929134381520694L;

	private Paint paint;
	
	public GridPanel() {
		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
	}

	@Override
	public String id() {
		return getName();
	}
	
	@Override
	public GridPanel id(String id) {
		setName(id);
		return this;
	}
	
	public LinePanel line() {
		LinePanel line = new LinePanel();
		add(line);
		return line;
	}
	
	public class LinePanel extends JPanel implements Widget<LinePanel>, WidgetPaint<LinePanel> {
		
		private static final long serialVersionUID = -6515210808215586435L;
		
		private Paint paint;

		public LinePanel() {
			super(new FlowLayout(FlowLayout.LEFT));
			opaque(false);
		}
		
		public LinePanel layout(Position position) {
			switch (position) {
			case LEFT:
				setLayout(new FlowLayout(FlowLayout.LEFT));
				break;
			case CENTER:
				setLayout(new FlowLayout(FlowLayout.CENTER));
				break;
			case RIGHT:
				setLayout(new FlowLayout(FlowLayout.RIGHT));
				break;
			case TOP:
			case BOTTOM:
				throw new IllegalArgumentException("Position TOP and BOTTOM are illegal to LinePanel");
			}
			return this;
		}
		
		public LinePanel opaque(boolean opaque) {
			setOpaque(opaque);
			return this;
		}
		
		public LinePanel add(Component c) {
			super.add(c);
			return this;
		}
		
		public String id() {
			return getName();
		}
		
		public LinePanel id(String id) {
			setName(id);
			return this;
		}

		public boolean visible() {
			return isVisible();
		}
		
		public LinePanel visible(boolean visible) {
			setVisible(visible);
			return this;
		}

		@Override
		public LinePanel paint(Paint paint) {
			this.paint = paint;
			return this;
		}

		@Override
		public LinePanel properties(Body<LinePanel> body) {
			body.content(this);
			return this;
		}

		@Override
		public Color background() {
			return getBackground();
		}

		@Override
		public LinePanel background(Color background) {
			setBackground(background);
			return this;
		}

		@Override
		public Color foreground() {
			return getForeground();
		}

		@Override
		public LinePanel foreground(Color foreground) {
			setForeground(foreground);
			return this;
		}

		@Override
		public LinePanel size(int width, int height) {
			setPreferredSize(new Dimension(width, height));
			return this;
		}

		@Override
		public Font font() {
			return getFont();
		}

		@Override
		public LinePanel font(Font font) {
			setFont(font);
			return this;
		}
		
		@Override
		public void paint(Graphics g) {
			if (paint != null)
				paint.paint((Graphics2D) g, this);
			
			super.paint(g);
		}
		
	}

	@Override
	public GridPanel properties(Body<GridPanel> body) {
		body.content(this);
		return this;
	}
	
	@Override
	public GridPanel size(int width, int height) {
		setPreferredSize(new Dimension(width, height));
		return this;
	}

	@Override
	public Color background() {
		return getBackground();
	}

	@Override
	public GridPanel background(Color background) {
		setBackground(background);
		return this;
	}

	@Override
	public Color foreground() {
		return getForeground();
	}

	@Override
	public GridPanel foreground(Color foreground) {
		setForeground(foreground);
		return this;
	}

	@Override
	public Font font() {
		return getFont();
	}

	@Override
	public GridPanel font(Font font) {
		setFont(font);
		return this;
	}
	
	public GridPanel opaque(boolean opaque) {
		setOpaque(opaque);
		return this;
	}

	public GridPanel paint(Paint paint) {
		this.paint = paint;
		return this;
	}

	@Override
	protected void paintComponent(Graphics g) {
		if (paint != null)
			paint.paint((Graphics2D) g, this);
		super.paintComponent(g);
	}
	
}
